package com.platform.boot.web.config.shiro;

import java.util.ArrayList;
import java.util.List;

import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.platform.common.utils.vo.LoginType;
import com.platform.common.utils.vo.UserToken;
import com.platform.system.api.constants.SysConfigConstant;
import com.platform.system.api.entity.sys.User;
import com.platform.system.api.entity.sys.UserPermission;
import com.platform.system.api.enums.sys.UserStatus;
import com.platform.system.api.service.sys.UserPermissionService;
import com.platform.system.api.service.sys.UserService;

import lombok.extern.slf4j.Slf4j;

/**
 * 用户密码登录realm
 */
@Slf4j
public class UserPasswordRealm extends AuthorizingRealm {
    
    @Autowired
    private UserService userService;

    @Autowired
    private UserPermissionService userPermissionService;

    @Override
    public String getName() {
        return LoginType.USER_PASSWORD.getType();
    }

    @Override
    public boolean supports(AuthenticationToken token) {
        if (token instanceof UserToken) {
            return ((UserToken) token).getLoginType() == LoginType.USER_PASSWORD;
        } else {
            return false;
        }
    }

    @Override
    public void setAuthorizationCacheName(String authorizationCacheName) {
        super.setAuthorizationCacheName(authorizationCacheName);
    }

    @Override
    protected void clearCachedAuthorizationInfo(PrincipalCollection principals) {
        super.clearCachedAuthorizationInfo(principals);

    }
    /**
     * 认证信息.(身份验证) : Authentication 是用来验证用户身份
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
    	long start = System.currentTimeMillis();
		String email = (String) token.getPrincipal();
		User user = null;
		// 获取Session
		Subject currentUser = SecurityUtils.getSubject();
		Session session = currentUser.getSession();
		if (StringUtils.isNotEmpty(email)) {
			// 注册人的email 唯一
				Wrapper<User> wrapper1 = new EntityWrapper<>();
				wrapper1.where("email = {0}", email);
				user = userService.selectOne(wrapper1 );
			if (user == null) {
				throw new AuthenticationException("账号不存在");
			}
			if(!user.getSysManager()&&!user.getCompanyManager()){
				List<UserPermission> userPermissions=new ArrayList<UserPermission>();
				Wrapper<UserPermission> wrapper2 = new EntityWrapper<>();
				wrapper2.where("user_id = {0}", user.getId());
				userPermissions=userPermissionService.selectList(wrapper2 );//
				if(userPermissions==null||userPermissions.size()==0){
					throw new AuthenticationException("该账号未授权");// 该账号未授权
				}
			}
		}
		if (null == user.getLock() || ( user.getLock()).equals("2")) {//1 没有锁定 2 已锁定
			throw new AuthenticationException("帐号已锁定"); // 帐号锁定
		}
		if (null == user.getStatus() || user.getStatus() == UserStatus.UNABLED) {
			throw new AuthenticationException("请先激活您注册的帐号"); // 
		}
		// 交给AuthenticatingRealm使用CredentialsMatcher进行密码匹配，自定义实现
		SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(//
				user.getEmail(), // 用户名
				user.getPassword(), // 密码
				ByteSource.Util.bytes(SysConfigConstant.MD5_KEY), // salt固定
				getName() // realm name
		);
		// 将登录信息放入session
		session.setAttribute(SysConfigConstant.LOGIN_KEY, user);
		long end = System.currentTimeMillis();
		log.info("UserRealm认证耗费时间：" + (end - start) + "毫秒");
		return authenticationInfo;
    }

    /**
     * 授权
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
    	System.out.println("授权");
    	return null;
    }
}
